package com.example.maax.controller;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import com.example.maax.entity.Device;
import com.example.maax.entity.Task;
import com.example.maax.mapper.DeviceMapper;
import com.example.maax.mapper.TaskMapper;
import com.example.maax.vo.RemoteReqDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.List;

@RestController
@RequestMapping("/remote")
@RequiredArgsConstructor
public class RemoteController {
    public static final String SUCCESS = "SUCCESS";
    public static final String HEART_BEAT = "HeartBeat";

    private final DeviceMapper deviceMapper;
    private final TaskMapper taskMapper;

    @PostMapping("/getTask")
    public String getTask(@RequestBody RemoteReqDTO reqVO) {
        List<Task> list = ChainWrappers.lambdaQueryChain(deviceMapper)
                .eq(Device::getCode, reqVO.getDevice())
                .oneOpt()
                .map(device -> ChainWrappers.lambdaQueryChain(taskMapper)
                        .select(Task::getId, Task::getUserId, Task::getDeviceId, Task::getType, Task::getParams)
                        .eq(Task::getUserId, device.getUserId())
                        .eq(Task::getDeviceId, device.getId())
                        .eq(Task::getStatus, 1)
                        .orderByAsc(List.of(Task::getCreateTime, Task::getId))
                        .list())
                .orElseThrow();
        if (!list.isEmpty() && list.stream().noneMatch(el -> HEART_BEAT.equals(el.getType()))) {
            Task t = list.get(0);

            Task task = new Task();
            task.setUserId(t.getUserId());
            task.setDeviceId(t.getDeviceId());
            task.setType(HEART_BEAT);
            task.setStatus(1);
            task.setCreateTime(LocalDateTime.now());
            task.setUpdateTime(task.getCreateTime());
            taskMapper.insert(task);

            list.add(task);
        }
        return JSONObject.of("tasks", list).toString();
    }

    @PostMapping("/reportTask")
    public String reportTask(@RequestBody RemoteReqDTO reqVO) {
        Task task = taskMapper.selectById(reqVO.getTask());
        if (task != null) {
            boolean success = SUCCESS.equals(reqVO.getStatus());
            if (HEART_BEAT.equals(task.getType())) {
                ChainWrappers.lambdaUpdateChain(taskMapper)
                        .eq(Task::getId, reqVO.getPayload())
                        .eq(Task::getStatus, 1)
                        .set(Task::getStatus, success ? 2 : 4)
                        .set(Task::getUpdateTime, LocalDateTime.now())
                        .update();
                taskMapper.deleteById(task);
            } else {
                ChainWrappers.lambdaUpdateChain(taskMapper)
                        .eq(Task::getId, task.getId())
                        .in(Task::getStatus, 1, 2)
                        .set(Task::getStatus, success ? 3 : 4)
                        .set(Task::getPayload, reqVO.getPayload())
                        .set(Task::getUpdateTime, LocalDateTime.now())
                        .update();
            }
        }
        return "ok";
    }
}
